home *** CD-ROM | disk | FTP | other *** search
- Attribute VB_Name = "BinaryMgmt"
- 'Database will be a random access text file database
- 'List will be a random access text file database with just the headers
-
- Public DatabasePath As String
- Public BackupDatabasePath As String
- Public IndexPath As String
- Public dirty As Boolean
- Public Any_Change_At_All As Boolean
-
- 'this is the delimiter I chose--you can choose another kind if you want
- Public Const DOT = "ñ"
-
- 'this is the tombstone marker--you can choose another kind if you want
- Public Const TOMBSTONE = "@TOMBSTONE@"
-
- Private Const DATABASE_RECORD_LIMIT = 65000 'just set it at any limit--it could actually be greater
-
- 'you can customize column width without hurting data--i just set it to 20 to make it look nice in listbox
- Private Const COLUMN_WIDTH = 20
-
- 'you can change these to any unique filenames you want
- Private Const DATABASE_NAME = "Inbox.mbx"
- Private Const INDEX_NAME = "Inbox.idx"
- Private Const BACKUP_DATABASE_NAME = "Inbox.mb0"
- Private Const BACKUP_INDEX_NAME = "inbox.id0"
-
- 'this indicates where in the IDX (index) file the field for displaying that value is.
- Private Const START_BYTE_PART = 1
- Private Const LEN_BYTE_PART = 2
- Private Const FROM_PART = 3
- Private Const SUBJECT_PART = 4
- Private Const DATE_PART = 5
- Private Const TO_PART = 6
- Private Const INDEX_PART = 7
-
-
-
- Public Sub AddRecord()
- On Error Resume Next
- Any_Change_At_All = True
- frmRec.txtDate = Now
- recnext& = CLng(Val(ReadIndex("RecNext")))
- frmRec.txtIndex = recnext& & ""
- frmRec.Show 1
- BinaryMgmt.AddRecordFinish
- Unload frmRec
-
- On Error GoTo 0
- On Error Resume Next
- End Sub
-
- Private Sub AddRecordFinish()
- On Error Resume Next
- Dim message As String
- message = Trim(frmRec.txtMessage)
-
- Open DatabasePath For Binary As #1
- byte_next = ReadIndex("ByteNext")
- rec_next = ReadIndex("RecNext")
- Put #1, byte_next, message
- Close #1
-
- len_bytes = Len(message)
- v$ = byte_next & DOT & len_bytes & DOT & Trim(frmRec.txtFrom) & DOT & Trim(frmRec.txtSubject) & DOT & Trim(frmRec.txtDate) & DOT & Trim(frmRec.txtTo) & DOT & "OK"
- WriteIndex "R" & rec_next, v$
- byte_next = byte_next + len_bytes
- WriteIndex "ByteNext", byte_next
- rec_next = rec_next + 1
- WriteIndex "RecNext", rec_next
- ReadAllRecords
- On Error GoTo 0
- On Error Resume Next
- End Sub
-
- Public Sub EditRecord()
- On Error Resume Next
- If frmMain.List1.ListIndex = 0 Then Exit Sub
- v$ = frmMain.List1.List(frmMain.List1.ListIndex)
- myindex = ParseTab(v$, 5): v$ = ""
- frmRec.txtIndex = myindex
- v$ = ReadIndex("R" & myindex)
- start_byte& = CLng(Val(Parse(v$, START_BYTE_PART)))
- len_bytes& = CLng(Val(Parse(v$, LEN_BYTE_PART)))
- Dim filebuffer As String
- filebuffer = String(len_bytes&, 0)
- Open DatabasePath For Binary As #1
- Get #1, start_byte&, filebuffer
- Close #1
- frmRec.txtDate = Parse(v$, DATE_PART)
- frmRec.txtTo = Parse(v$, TO_PART)
- frmRec.txtFrom = Parse(v$, FROM_PART)
- frmRec.txtSubject = Parse(v$, SUBJECT_PART)
- frmRec.txtMessage = Mid$(filebuffer, 1, len_bytes&)
- frmRec.Show 1
- If dirty = True Then
- BinaryMgmt.EditRecordFinish
- dirty = False
- End If
- Unload frmRec
- On Error GoTo 0
- On Error Resume Next
- End Sub
-
- Private Sub EditRecordFinish()
- On Error Resume Next
- Any_Change_At_All = True
- Dim message As String
- message = Trim(frmRec.txtMessage)
-
- 'tombstone the current record
- myindex = Trim(frmRec.txtIndex)
- readin$ = ReadIndex("R" & CLng(Val(myindex)))
- readin$ = Left(readin$, Len(readin$) - 2) 'strip off ok on end
- readin$ = readin$ & "@TOMBSTONE@"
- WriteIndex "R" & CLng(Val(myindex)), readin$
-
- 'write new record to end of database
- Open DatabasePath For Binary As #1
- byte_next = ReadIndex("ByteNext")
- rec_next = ReadIndex("RecNext")
- Put #1, byte_next, message
- Close #1
-
- 'write new record to end of index
- len_bytes = Len(message)
- v$ = byte_next & DOT & len_bytes & DOT & Trim(frmRec.txtFrom) & DOT & Trim(frmRec.txtSubject) & DOT & Trim(frmRec.txtDate) & DOT & Trim(frmRec.txtTo) & DOT & "OK"
- WriteIndex "R" & rec_next, v$
- byte_next = byte_next + len_bytes
- WriteIndex "ByteNext", byte_next
- rec_next = rec_next + 1
- WriteIndex "RecNext", rec_next
-
- 'redisplay all records
- ReadAllRecords
- On Error GoTo 0
- On Error Resume Next
- End Sub
-
- Public Sub DeleteRecord()
- On Error Resume Next
- Any_Change_At_All = True
- 'tombstone the current record
- If frmMain.List1.ListIndex = 0 Then Exit Sub
- v$ = frmMain.List1.List(frmMain.List1.ListIndex)
- myindex = ParseTab(v$, 5): v$ = ""
- readin$ = ReadIndex("R" & CLng(Val(myindex)))
- readin$ = Left(readin$, Len(readin$) - 2) 'strip off ok on end
- readin$ = readin$ & "@TOMBSTONE@"
- WriteIndex "R" & CLng(Val(myindex)), readin$
-
- 'redisplay records
- ReadAllRecords
- On Error GoTo 0
- On Error Resume Next
- End Sub
-
-
-
- Public Sub ReadAllRecords()
- On Error Resume Next
- frmMain.List1.Clear
- BuildHeaderList
- v$ = "dummytext"
- Do
- k& = k& + 1
- v$ = ReadIndex("R" & k&)
- If v$ = "" Then Exit Do
- 'read all records that aren't tombstones
- If Right$(v$, Len(TOMBSTONE)) <> TOMBSTONE Then
- frmMain.List1.AddItem _
- Pad(Parse(v$, FROM_PART)) & vbTab & _
- Pad(Parse(v$, SUBJECT_PART)) & vbTab & _
- Pad(Parse(v$, DATE_PART)) & vbTab & _
- Pad(Parse(v$, TO_PART)) & vbTab & _
- k&
- End If
- Loop Until v$ = ""
- On Error GoTo 0
- On Error Resume Next
- End Sub
-
- Public Sub OpenDatabase()
- On Error Resume Next
- DatabasePath = App.Path
- If Right$(DatabasePath, 1) <> "\" Then DatabasePath = DatabasePath + "\"
- DatabasePath = DatabasePath + DATABASE_NAME
- IndexPath = App.Path
- If Right$(IndexPath, 1) <> "\" Then IndexPath = IndexPath + "\"
- IndexPath = IndexPath + INDEX_NAME
-
- If Not FileExists(DatabasePath) Then 'create file
- Open DatabasePath For Output As #1
- Close #1
- Open IndexPath For Output As #1
- Print #1, "[Index]"
- Print #1, "RecNext = 1"
- Print #1, "ByteNext = 1"
- Close #1
- End If
- On Error GoTo 0
- On Error Resume Next
-
- End Sub
-
- Private Function FileExists(ByVal f$) As Boolean
- On Error Resume Next
- SetAttr f$, vbNormal
- If Err Then
- FileExists = False
- Else
- FileExists = True
- End If
- On Error GoTo 0
- On Error Resume Next
- End Function
-
-
- Private Function Pad(ByVal incoming As String) As String
- On Error Resume Next
- Select Case Len(incoming)
- Case Is < COLUMN_WIDTH
- incoming = incoming & Space(COLUMN_WIDTH - Len(incoming))
- Case Is > COLUMN_WIDTH
- incoming = Left$(incoming, COLUMN_WIDTH)
- End Select
- Pad = incoming
- On Error GoTo 0
- On Error Resume Next
- End Function
-
- Private Sub BuildHeaderList()
- On Error Resume Next
- Dim colheaders(5) As String
- colheaders(1) = "From"
- colheaders(2) = "Subject"
- colheaders(3) = "Date"
- colheaders(4) = "To"
- colheaders(5) = "ID"
- For k% = 1 To 5
- header_row = header_row & Pad(colheaders(k%)) & " " & vbTab
- Next k%
- frmMain.List1.AddItem header_row
- On Error GoTo 0
- On Error Resume Next
- End Sub
-
- Public Sub CompactDatabase()
- 'Exit Sub
- 'BREAK
- On Error Resume Next
-
- readin = 1
- readout = 2
-
- 'kill last database backup and backup the current database file, then kill database file
- BackupDatabasePath = App.Path
- If Right$(BackupDatabasePath, 1) <> "\" Then BackupDatabasePath = BackupDatabasePath & "\"
- BackupDatabasePath = BackupDatabasePath + BACKUP_DATABASE_NAME
- Kill BackupDatabasePath
- FileCopy DatabasePath, BackupDatabasePath 'BackupDatabasePath is now the old database
- Kill DatabasePath 'so it can now hold the new database
-
- 'open backup (database needing compaction) and copy the non-orphaned bytes out to the new database
- Dim filebuffer As String
- byte_next& = 1
- Open BackupDatabasePath For Binary As #readin
- Open DatabasePath For Binary As #readout
- For k& = 1 To DATABASE_RECORD_LIMIT
- v$ = ReadIndex("R" & k&)
- If v$ = "" Then Exit For
- If Right$(v$, Len(TOMBSTONE)) <> TOMBSTONE Then 'read non-orphaned bytes
- start_byte& = CLng(Val(Parse(v$, START_BYTE_PART)))
- len_bytes& = CLng(Val(Parse(v$, LEN_BYTE_PART)))
- filebuffer = String(len_bytes&, 0)
- Get #readin, start_byte&, filebuffer
- outgoing$ = Mid$(filebuffer, 1, len_bytes&)
- Put #readout, byte_next&, outgoing$
- 'adjust the starting byte for the index record
- v$ = byte_next& & DOT & Parse(v$, LEN_BYTE_PART) & DOT & Parse(v$, FROM_PART) & DOT & Parse(v$, SUBJECT_PART) & DOT & Parse(v$, DATE_PART) & DOT & Parse(v$, TO_PART) & DOT & "OK"
- 'prepare to store stuff at a point just past the previous record
- 'write new record back to indexed record, but in newindex
- WriteIndex "R" & k&, v$
- byte_next& = byte_next& + len_bytes&
- Else
- 'shorten index file bytes
- WriteIndex "R" & k&, "@TOMBSTONE@"
- End If
- Next
- 'just in case the database has no records, make the next byte be 1
- If byte_next& = 0 Then byte_next& = 1
- 'adjust the RecNext and ByteNext fields
- WriteIndex "ByteNext", byte_next&
- WriteIndex "RecNext", k&
- Close #readout
- Close #readin
- Kill BackupDatabasePath
- On Error GoTo 0
- On Error Resume Next
- End Sub
-